+Sun Jul 11 15:24:03 2004 Soeren Sandmann <sandmann@daimi.au.dk>
+
+ Bug 143330, support update counter spec.
+
+ * configure.in: Add check for the Sync extension
+
+ * gdk/gdkwindow.h: gdk_window_enable_synchronized_configure() and
+ gdk_window_configure_finished()
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Call gdk_window_finish_configure().
+ * gtk/gtkwindow.c (gtk_window_realize): Automatically enable
+ synchronized configures.
+
+ * gdk/x11/gdkwindow-x11.h (struct _GdkToplevelX11): Store current
+ and pending counter values.
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_configure_finished): New function.
+ * gdk/x11/gdkwindow-x11.c
+ (gdk_window_enable_synchronized_configure): New function.
+ * gdk/x11/gdkwindow-x11.c (gdk_toplevel_x11_free_contents):
+ Delete update counter.
+ * gdk/x11/gdkwindow-x11.c (set_wm_protocols): Advertise
+ _NET_WM_SYNC_REQUEST when Sync is available
+
+ * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter): Handle
+ _NET_WM_SYNC_REQUEST messages
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Save counter
+ value for use by gdk_window_configure_finished() when receiving
+ ConfigureNotifies.
+
+ * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add use_sync flag
+ * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Check if the XSync
+ extension is available
+ * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_SYNC_REQUEST and
+ _NET_WM_SYNC_REQUEST_COUNTER to list of supported atoms.
+
+ * gdk/linux-fb/gdkwindow-fb.c, gdk/win32/gdkwindow-win32.c: Add
+ stubs for enable_synchronized_configure() and configure_finished()
+
Sat Jul 10 23:35:13 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtkentry.c (paste_received): Make middle-button pasting
+Sun Jul 11 15:24:03 2004 Soeren Sandmann <sandmann@daimi.au.dk>
+
+ Bug 143330, support update counter spec.
+
+ * configure.in: Add check for the Sync extension
+
+ * gdk/gdkwindow.h: gdk_window_enable_synchronized_configure() and
+ gdk_window_configure_finished()
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Call gdk_window_finish_configure().
+ * gtk/gtkwindow.c (gtk_window_realize): Automatically enable
+ synchronized configures.
+
+ * gdk/x11/gdkwindow-x11.h (struct _GdkToplevelX11): Store current
+ and pending counter values.
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_configure_finished): New function.
+ * gdk/x11/gdkwindow-x11.c
+ (gdk_window_enable_synchronized_configure): New function.
+ * gdk/x11/gdkwindow-x11.c (gdk_toplevel_x11_free_contents):
+ Delete update counter.
+ * gdk/x11/gdkwindow-x11.c (set_wm_protocols): Advertise
+ _NET_WM_SYNC_REQUEST when Sync is available
+
+ * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter): Handle
+ _NET_WM_SYNC_REQUEST messages
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Save counter
+ value for use by gdk_window_configure_finished() when receiving
+ ConfigureNotifies.
+
+ * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add use_sync flag
+ * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Check if the XSync
+ extension is available
+ * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_SYNC_REQUEST and
+ _NET_WM_SYNC_REQUEST_COUNTER to list of supported atoms.
+
+ * gdk/linux-fb/gdkwindow-fb.c, gdk/win32/gdkwindow-win32.c: Add
+ stubs for enable_synchronized_configure() and configure_finished()
+
Sat Jul 10 23:35:13 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtkentry.c (paste_received): Make middle-button pasting
+Sun Jul 11 15:24:03 2004 Soeren Sandmann <sandmann@daimi.au.dk>
+
+ Bug 143330, support update counter spec.
+
+ * configure.in: Add check for the Sync extension
+
+ * gdk/gdkwindow.h: gdk_window_enable_synchronized_configure() and
+ gdk_window_configure_finished()
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Call gdk_window_finish_configure().
+ * gtk/gtkwindow.c (gtk_window_realize): Automatically enable
+ synchronized configures.
+
+ * gdk/x11/gdkwindow-x11.h (struct _GdkToplevelX11): Store current
+ and pending counter values.
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_configure_finished): New function.
+ * gdk/x11/gdkwindow-x11.c
+ (gdk_window_enable_synchronized_configure): New function.
+ * gdk/x11/gdkwindow-x11.c (gdk_toplevel_x11_free_contents):
+ Delete update counter.
+ * gdk/x11/gdkwindow-x11.c (set_wm_protocols): Advertise
+ _NET_WM_SYNC_REQUEST when Sync is available
+
+ * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter): Handle
+ _NET_WM_SYNC_REQUEST messages
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Save counter
+ value for use by gdk_window_configure_finished() when receiving
+ ConfigureNotifies.
+
+ * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add use_sync flag
+ * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Check if the XSync
+ extension is available
+ * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_SYNC_REQUEST and
+ _NET_WM_SYNC_REQUEST_COUNTER to list of supported atoms.
+
+ * gdk/linux-fb/gdkwindow-fb.c, gdk/win32/gdkwindow-win32.c: Add
+ stubs for enable_synchronized_configure() and configure_finished()
+
Sat Jul 10 23:35:13 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtkentry.c (paste_received): Make middle-button pasting
+Sun Jul 11 15:24:03 2004 Soeren Sandmann <sandmann@daimi.au.dk>
+
+ Bug 143330, support update counter spec.
+
+ * configure.in: Add check for the Sync extension
+
+ * gdk/gdkwindow.h: gdk_window_enable_synchronized_configure() and
+ gdk_window_configure_finished()
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Call gdk_window_finish_configure().
+ * gtk/gtkwindow.c (gtk_window_realize): Automatically enable
+ synchronized configures.
+
+ * gdk/x11/gdkwindow-x11.h (struct _GdkToplevelX11): Store current
+ and pending counter values.
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_configure_finished): New function.
+ * gdk/x11/gdkwindow-x11.c
+ (gdk_window_enable_synchronized_configure): New function.
+ * gdk/x11/gdkwindow-x11.c (gdk_toplevel_x11_free_contents):
+ Delete update counter.
+ * gdk/x11/gdkwindow-x11.c (set_wm_protocols): Advertise
+ _NET_WM_SYNC_REQUEST when Sync is available
+
+ * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter): Handle
+ _NET_WM_SYNC_REQUEST messages
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Save counter
+ value for use by gdk_window_configure_finished() when receiving
+ ConfigureNotifies.
+
+ * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add use_sync flag
+ * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Check if the XSync
+ extension is available
+ * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_SYNC_REQUEST and
+ _NET_WM_SYNC_REQUEST_COUNTER to list of supported atoms.
+
+ * gdk/linux-fb/gdkwindow-fb.c, gdk/win32/gdkwindow-win32.c: Add
+ stubs for enable_synchronized_configure() and configure_finished()
+
Sat Jul 10 23:35:13 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtkentry.c (paste_received): Make middle-button pasting
GDK_EXTRA_LIBS="`$PKG_CONFIG --libs xcursor` $GDK_EXTRA_LIBS"
fi
+ # X SYNC check
+ AC_CHECK_LIB(Xext, XSyncQueryExtension,
+ [GTK_ADD_LIB(x_extra_libs,Xext)
+ AC_DEFINE([HAVE_XSYNC], [], [Have SYNC extension])],
+ ,$x_libs_for_checks)
+
# Checks for XFixes extension
have_xfixes=false
gint *x_offset,
gint *y_offset);
+void gdk_window_enable_synchronized_configure (GdkWindow *window);
+void gdk_window_configure_finished (GdkWindow *window);
+
#ifndef GDK_MULTIHEAD_SAFE
GdkPointerHooks *gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks);
#endif /* GDK_MULTIHEAD_SAFE */
return (GdkWindow*) (anid);
}
+
+void
+gdk_window_enable_synchronized_configure (GdkWindow *window)
+{
+}
+
+void
+gdk_window_configure_finished (GdkWindow *window)
+{
+}
return gdk_window_lookup (anid);
}
+
+void
+gdk_window_enable_synchronized_configure (GdkWindow *window)
+{
+}
+
+void
+gdk_window_configure_finished (GdkWindow *window);
+{
+}
"_NET_WM_STATE_MAXIMIZED_VERT",
"_NET_WM_STATE_MAXIMIZED_HORZ",
"_NET_WM_STATE_FULLSCREEN",
+ "_NET_WM_SYNC_REQUEST",
+ "_NET_WM_SYNC_REQUEST_COUNTER",
"_NET_WM_WINDOW_TYPE",
"_NET_WM_WINDOW_TYPE_NORMAL",
"_NET_WM_USER_TIME",
}
#endif
+ display_x11->use_sync = FALSE;
+#ifdef HAVE_XSYNC
+ {
+ int major, minor;
+ int error_base, event_base;
+
+ if (XSyncQueryExtension (display_x11->xdisplay,
+ &event_base, &error_base) &&
+ XSyncInitialize (display_x11->xdisplay,
+ &major, &minor))
+ display_x11->use_sync = TRUE;
+ }
+#endif
+
_gdk_windowing_image_init (display);
_gdk_events_init (display);
_gdk_input_init (display);
guint base_dnd_atoms_precached : 1;
guint xdnd_atoms_precached : 1;
guint motif_atoms_precached : 1;
+ guint use_sync : 1;
};
struct _GdkDisplayX11Class
#include <X11/XKBlib.h>
#endif
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
#ifdef HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
#endif
display_sources = g_list_prepend (display_sources,display_source);
- gdk_display_add_client_message_filter (
- display,
- gdk_atom_intern ("WM_PROTOCOLS", FALSE),
- gdk_wm_protocols_filter,
- NULL);
+ gdk_display_add_client_message_filter (display,
+ gdk_atom_intern ("WM_PROTOCOLS", FALSE),
+ gdk_wm_protocols_filter,
+ NULL);
}
!GDK_WINDOW_DESTROYED (window) &&
(window_private->extension_events != 0))
_gdk_input_configure_event (&xevent->xconfigure, window);
+
+#ifdef HAVE_XSYNC
+ if (toplevel && display_x11->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
+ {
+ toplevel->current_counter_value = toplevel->pending_counter_value;
+ XSyncIntToValue (&toplevel->pending_counter_value, 0);
+ }
+#endif
- if (!window ||
+ if (!window ||
xevent->xconfigure.event != xevent->xconfigure.window ||
GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
XEvent *xevent = (XEvent *)xev;
GdkWindow *win = event->any.window;
GdkDisplay *display = GDK_WINDOW_DISPLAY (win);
+ Atom atom = (Atom)xevent->xclient.data.l[0];
- if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
+ if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
{
/* The delete window request specifies a window
* to delete. We don't actually destroy the
return GDK_FILTER_TRANSLATE;
}
- else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
{
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
GdkWindowObject *private = (GdkWindowObject *)win;
return GDK_FILTER_REMOVE;
}
- else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
!_gdk_x11_display_is_root_window (display,
xevent->xclient.window))
{
return GDK_FILTER_REMOVE;
}
-
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST") &&
+ GDK_DISPLAY_X11 (display)->use_sync)
+ {
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
+ if (toplevel)
+ {
+#ifdef HAVE_XSYNC
+ XSyncIntsToValue (&toplevel->pending_counter_value,
+ xevent->xclient.data.l[2],
+ xevent->xclient.data.l[3]);
+#endif
+ }
+ return GDK_FILTER_REMOVE;
+ }
+
return GDK_FILTER_CONTINUE;
}
set_wm_protocols (GdkWindow *window)
{
GdkDisplay *display = gdk_drawable_get_display (window);
- Atom protocols[3];
+ Atom protocols[4];
+ int n = 0;
- protocols[0] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
- protocols[1] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
- protocols[2] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
+ protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
+ protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
+ protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
- XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, 3);
+#ifdef HAVE_XSYNC
+ if (GDK_DISPLAY_X11 (display)->use_sync)
+ protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST");
+#endif
+
+ XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
}
static const gchar *
}
static void
-setup_toplevel_window (GdkWindow *window, GdkWindow *parent)
+setup_toplevel_window (GdkWindow *window,
+ GdkWindow *parent)
{
GdkWindowObject *obj = (GdkWindowObject *)window;
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
}
static void
-gdk_toplevel_x11_free_contents (GdkToplevelX11 *toplevel)
+gdk_toplevel_x11_free_contents (GdkDisplay *display,
+ GdkToplevelX11 *toplevel)
{
if (toplevel->icon_window)
{
g_object_unref (toplevel->group_leader);
toplevel->group_leader = NULL;
}
+ if (toplevel->update_counter != None)
+ {
+#ifdef HAVE_XSYNC
+ XSyncDestroyCounter (GDK_DISPLAY_XDISPLAY (display),
+ toplevel->update_counter);
+ toplevel->update_counter = None;
+
+ XSyncIntToValue (&toplevel->current_counter_value, 0);
+ XSyncIntToValue (&toplevel->pending_counter_value, 0);
+#endif
+ }
}
void
toplevel = _gdk_x11_window_get_toplevel (window);
if (toplevel)
- gdk_toplevel_x11_free_contents (toplevel);
+ gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
_gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
}
- gdk_toplevel_x11_free_contents (impl->toplevel);
+ gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window),
+ impl->toplevel);
g_free (impl->toplevel);
impl->toplevel = NULL;
}
else
emulate_move_drag (window, button, root_x, root_y, timestamp);
}
+
+/**
+ * gdk_window_enable_synchronized_configure:
+ * @window: a toplevel #GdkWindow
+ *
+ * Indicates that the application will cooperate with the window
+ * system in synchronizing the window repaint with the window
+ * manager during resizing operations. After an application calls
+ * this function, it must call gdk_window_configure_finished() every
+ * time it has finished all processing associated with a set of
+ * Configure events. Toplevel GTK+ windows automatically use this
+ * protocol.
+ *
+ * On X, calling this function makes @window participate in the
+ * _NET_WM_SYNC_REQUEST window manager protocol.
+ *
+ * Since: 2.6
+ **/
+void
+gdk_window_enable_synchronized_configure (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+#ifdef HAVE_XSYNC
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+
+ if (toplevel && toplevel->update_counter == None &&
+ GDK_DISPLAY_X11 (display)->use_sync)
+ {
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+ XSyncValue value;
+ Atom atom;
+
+ if (toplevel->update_counter != None)
+ return;
+
+ XSyncIntToValue (&value, 0);
+
+ toplevel->update_counter = XSyncCreateCounter (xdisplay, value);
+
+ atom = gdk_x11_get_xatom_by_name_for_display (display,
+ "_NET_WM_SYNC_REQUEST_COUNTER");
+
+ XChangeProperty (xdisplay, GDK_WINDOW_XID (window),
+ atom, XA_CARDINAL,
+ 32, PropModeReplace,
+ (guchar *)&toplevel->update_counter, 1);
+
+ XSyncIntToValue (&toplevel->current_counter_value, 0);
+ }
+ }
+#endif /* HAVE_XSYNC */
+}
+
+/**
+ * gdk_window_configure_finished:
+ * @window: a toplevel #GdkWindow
+ *
+ * Signal to the window system that the application has finished
+ * handling Configure events it has received. Window Managers can
+ * use this to better synchronize the frame repaint with the
+ * application. GTK+ applications will automatically call this
+ * function when appropriate.
+ *
+ * This function can only be called if gdk_window_use_configure()
+ * was called previously.
+ *
+ * Since: 2.6
+ **/
+void
+gdk_window_configure_finished (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+#ifdef HAVE_XSYNC
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+
+ g_return_if_fail (toplevel->update_counter != None);
+
+ if (toplevel && GDK_DISPLAY_X11 (display)->use_sync &&
+ !XSyncValueIsZero (toplevel->current_counter_value))
+ {
+ XSyncSetCounter (GDK_WINDOW_XDISPLAY (window),
+ toplevel->update_counter,
+ toplevel->current_counter_value);
+
+ XSyncIntToValue (&toplevel->current_counter_value, 0);
+ }
+ }
+#endif
+}
#include <gdk/x11/gdkdrawable-x11.h>
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
G_BEGIN_DECLS
typedef struct _GdkToplevelX11 GdkToplevelX11;
* that might not even be part of this app
*/
Window focus_window;
+
+#ifdef HAVE_XSYNC
+ XID update_counter;
+ XSyncValue pending_counter_value; /* latest _NET_WM_SYNC_REQUEST value received */
+ XSyncValue current_counter_value; /* Latest _NET_WM_SYNC_REQUEST value received
+ * where we have also seen the corresponding
+ * ConfigureNotify
+ */
+#endif
};
GType gdk_window_impl_x11_get_type (void);
-GdkToplevelX11 *_gdk_x11_window_get_toplevel (GdkWindow *window);
void gdk_x11_window_set_user_time (GdkWindow *window,
guint32 timestamp);
+
+GdkToplevelX11 *_gdk_x11_window_get_toplevel (GdkWindow *window);
void _gdk_x11_window_tmp_unset_bg (GdkWindow *window,
gboolean recurse);
void _gdk_x11_window_tmp_reset_bg (GdkWindow *window,
attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
+
+ gdk_window_enable_synchronized_configure (widget->window);
gdk_window_set_user_data (widget->window, window);
if (!expected_reply &&
(widget->allocation.width == event->width &&
widget->allocation.height == event->height))
- return TRUE;
+ {
+ gdk_window_configure_finished (widget->window);
+ return TRUE;
+ }
/*
* If we do need to resize, we do that by:
allocation = widget->allocation;
gtk_widget_size_allocate (widget, &allocation);
+ gdk_window_process_all_updates ();
+
+ gdk_window_configure_finished (widget->window);
+
/* If the configure request changed, it means that
* we either:
* 1) coincidentally changed hints or widget properties